// Server2 is a minimal "echo" and counter server.
package main

import (
	"fmt"
	"image"
	"image/color"
	"image/gif"
	"io"
	"log"
	"math"
	"math/rand"
	"net/http"
	"strconv"
	"sync"
)

var mu sync.Mutex
var count int

var palette = []color.Color{color.White, color.RGBA{0x00, 0xff, 0x00, 0xff}, color.RGBA{0xff, 0x00, 0x00, 0xff}, color.RGBA{0x00, 0x00, 0xff, 0xff}}

func main() {
	http.HandleFunc("/", handler)
	log.Fatal(http.ListenAndServe("localhost:8000", nil))
}

// handler echoes the Path component of the requested URL.
func handler(w http.ResponseWriter, r *http.Request) {
	var conf = newDefault()
	// 分析 form 参数
	if err := r.ParseForm(); err != nil {
		log.Print(err)
	}
	for k, v := range r.Form {
		switch k {
		case "cycles":
			conf.cycles, _ = strconv.Atoi(v[0])
		case "res":
			conf.res, _ = strconv.ParseFloat(v[0], 64)
		case "size":
			conf.size, _ = strconv.Atoi(v[0])
		case "nframes":
			conf.nframes, _ = strconv.Atoi(v[0])
		case "delay":
			conf.delay, _ = strconv.Atoi(v[0])
		}
	}
	fmt.Println(conf)
	lissajous(w, conf)

}

type LissajousValue struct {
	cycles  int
	res     float64
	size    int
	nframes int
	delay   int
}

func newDefault() *LissajousValue {
	return &LissajousValue{
		cycles:  5,
		res:     0.001,
		size:    100,
		nframes: 64,
		delay:   8,
	}
}

func lissajous(out io.Writer, conf *LissajousValue) {
	// 常量的定义，定义之后不能更改
	// 这里是一种批量定义方式
	// 变量的类型编译器会根据后面的参数进行猜测
	var (
		cycles  = conf.cycles  // number of complete x oscillator revolutions
		res     = conf.res     // angular resolution
		size    = conf.size    // image canvas covers [-size..+size]
		nframes = conf.nframes // number of animation frames
		delay   = conf.delay   // delay between frames in 10ms units
	)

	freq := rand.Float64() * 3.0 // relative frequency of y oscillator
	anim := gif.GIF{LoopCount: nframes}
	phase := 0.0           // phase difference
	colorIndex := uint8(0) // 颜色索引
	for i := 0; i < nframes; i++ {
		rect := image.Rect(0, 0, 2*size+1, 2*size+1)
		img := image.NewPaletted(rect, palette)
		for t := 0.0; t < float64(cycles*2)*math.Pi; t += res {
			x := math.Sin(t)
			y := math.Sin(t*freq + phase)

			// 调色板选择其它颜色，让它变成彩色的
			colorIndex = uint8(t)%3 + 1
			img.SetColorIndex(size+int(x*float64(size)+0.5), size+int(y*float64(size)+0.5),
				colorIndex)
		}
		phase += 0.1
		anim.Delay = append(anim.Delay, delay)
		anim.Image = append(anim.Image, img)
	}
	gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors
}
